/******************************************************************************* * Copyright (c) 2004, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal.themes; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.ResourceBundle; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.resource.StringConverter; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; import org.eclipse.ui.internal.registry.RegistryReader; import org.eclipse.ui.themes.IColorFactory; /** * Registry reader for themes. * * @since 3.0 */ public class ThemeRegistryReader extends RegistryReader { /** * The translation bundle in which to look up internationalized text. */ private final static ResourceBundle RESOURCE_BUNDLE = ResourceBundle .getBundle(ThemeRegistryReader.class.getName()); private Collection categoryDefinitions = new HashSet(); private Collection colorDefinitions = new HashSet(); private Collection fontDefinitions = new HashSet(); private ThemeDescriptor themeDescriptor = null; private ThemeRegistry themeRegistry; private Map dataMap = new HashMap(); /** * ThemeRegistryReader constructor comment. */ public ThemeRegistryReader() { super(); } /** * Returns the category definitions. * * @return the category definitions */ public Collection getCategoryDefinitions() { return categoryDefinitions; } /** * Returns the color definitions. * * @return the color definitions */ public Collection getColorDefinitions() { return colorDefinitions; } /** * Returns the data map. * * @return the data map */ public Map getData() { return dataMap; } /** * Returns the font definitions. * * @return the font definitions */ public Collection getFontDefinitions() { return fontDefinitions; } /** * Read a category. * * @param element the element to read * @return the new category */ private ThemeElementCategory readCategory(IConfigurationElement element) { String name = element.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL); String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID); String parentId = element.getAttribute(IWorkbenchRegistryConstants.ATT_PARENT_ID); String description = null; IConfigurationElement[] descriptions = element .getChildren(IWorkbenchRegistryConstants.TAG_DESCRIPTION); if (descriptions.length > 0) { description = descriptions[0].getValue(); } return new ThemeElementCategory(name, id, parentId, description, element.getNamespace(), element); } /** * Read a color. * * @param element the element to read * @return the new color */ private ColorDefinition readColor(IConfigurationElement element) { String name = element.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL); String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID); String defaultMapping = element.getAttribute(IWorkbenchRegistryConstants.ATT_DEFAULTS_TO); String value = getPlatformSpecificColorValue(element .getChildren(IWorkbenchRegistryConstants.TAG_COLORVALUE)); if (value == null) { value = getColorValue(element); } if ((value == null && defaultMapping == null) || (value != null && defaultMapping != null)) { logError(element, RESOURCE_BUNDLE.getString("Colors.badDefault")); //$NON-NLS-1$ return null; } String categoryId = element.getAttribute(IWorkbenchRegistryConstants.ATT_CATEGORY_ID); String description = null; boolean isEditable = true; String isEditableString = element.getAttribute(IWorkbenchRegistryConstants.ATT_IS_EDITABLE); if (isEditableString != null) { isEditable = Boolean.valueOf(isEditableString).booleanValue(); } IConfigurationElement[] descriptions = element .getChildren(IWorkbenchRegistryConstants.TAG_DESCRIPTION); if (descriptions.length > 0) { description = descriptions[0].getValue(); } return new ColorDefinition(name, id, defaultMapping, value, categoryId, isEditable, description, element.getDeclaringExtension() .getNamespace()); } /** * Gets the color value, either via the value attribute or from a color * factory. * * @param element the element to check * @return the color string */ private String getColorValue(IConfigurationElement element) { if (element == null) { return null; } String value = element.getAttribute(IWorkbenchRegistryConstants.ATT_VALUE); if (value == null) { value = checkColorFactory(element); } return value; } /** * Check for platform specific color values. This will return the * "best match" for the current platform. * * @param elements the elements to check * @return the platform specific color, if any */ private String getPlatformSpecificColorValue( IConfigurationElement[] elements) { return getColorValue(getBestPlatformMatch(elements)); } /** * Get the element that has os/ws attributes that best match the current * platform. * * @param elements the elements to check * @return the best match, if any */ private IConfigurationElement getBestPlatformMatch( IConfigurationElement[] elements) { IConfigurationElement match = null; String osname = Platform.getOS(); String wsname = Platform.getWS(); for (IConfigurationElement element : elements) { String elementOs = element.getAttribute(IWorkbenchRegistryConstants.ATT_OS); String elementWs = element.getAttribute(IWorkbenchRegistryConstants.ATT_WS); if (osname.equalsIgnoreCase(elementOs)) { if (wsname.equalsIgnoreCase(elementWs)) { // best possible match. Return return element; } match = element; } else if (wsname.equalsIgnoreCase(elementWs)) { match = element; } } return match; } @Override public boolean readElement(IConfigurationElement element) { String elementName = element.getName(); if (themeDescriptor == null && elementName.equals(IWorkbenchRegistryConstants.TAG_COLORDEFINITION)) { ColorDefinition definition = readColor(element); if (definition != null) { if (!colorDefinitions.contains(definition)) { colorDefinitions.add(definition); themeRegistry.add(definition); } } return true; } else if (themeDescriptor != null && elementName.equals(IWorkbenchRegistryConstants.TAG_COLOROVERRIDE)) { ColorDefinition definition = readColor(element); if (definition != null) { themeDescriptor.add(definition); } return true; } else if (themeDescriptor == null && elementName.equals(IWorkbenchRegistryConstants.TAG_FONTDEFINITION)) { FontDefinition definition = readFont(element); if (definition != null) { if (!fontDefinitions.contains(definition)) { fontDefinitions.add(definition); themeRegistry.add(definition); } } return true; } else if (themeDescriptor != null && elementName.equals(IWorkbenchRegistryConstants.TAG_FONTOVERRIDE)) { FontDefinition definition = readFont(element); if (definition != null) { themeDescriptor.add(definition); } return true; } else if (themeDescriptor == null && elementName.equals(IWorkbenchRegistryConstants.TAG_CATEGORYDEFINITION)) { ThemeElementCategory definition = readCategory(element); if (definition != null) { if (!categoryDefinitions.contains(definition)) { categoryDefinitions.add(definition); themeRegistry.add(definition); } } return true; } else if (element.getName().equals(IWorkbenchRegistryConstants.TAG_THEME)) { if (themeDescriptor != null) { logError(element, RESOURCE_BUNDLE .getString("Themes.badNesting")); //$NON-NLS-1$ } else { themeDescriptor = readTheme(element); if (themeDescriptor != null) { readElementChildren(element); themeDescriptor = null; } return true; } } else if (themeDescriptor != null && elementName.equals(IWorkbenchRegistryConstants.TAG_DESCRIPTION)) { themeDescriptor.setDescription(element.getValue()); return true; } else if (elementName.equals(IWorkbenchRegistryConstants.TAG_DATA)) { String name = element.getAttribute(IWorkbenchRegistryConstants.ATT_NAME); String value = element.getAttribute(IWorkbenchRegistryConstants.ATT_VALUE); if (name == null || value == null) { logError(element, RESOURCE_BUNDLE.getString("Data.badData")); //$NON-NLS-1$ } else { if (themeDescriptor != null) { themeDescriptor.setData(name, value); } else { themeRegistry.setData(name, value); if (!dataMap.containsKey(name)) { dataMap.put(name, value); } } } return true; } return false; } /** * Read a font. * * @param element the element to read * @return the new font */ private FontDefinition readFont(IConfigurationElement element) { String name = element.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL); String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID); String defaultMapping = element.getAttribute(IWorkbenchRegistryConstants.ATT_DEFAULTS_TO); String value = getPlatformSpecificFontValue(element .getChildren(IWorkbenchRegistryConstants.TAG_FONTVALUE)); if (value == null) { value = element.getAttribute(IWorkbenchRegistryConstants.ATT_VALUE); } if (value != null && defaultMapping != null) { logError(element, RESOURCE_BUNDLE.getString("Fonts.badDefault")); //$NON-NLS-1$ return null; } String categoryId = element.getAttribute(IWorkbenchRegistryConstants.ATT_CATEGORY_ID); boolean isEditable = true; String isEditableString = element.getAttribute(IWorkbenchRegistryConstants.ATT_IS_EDITABLE); if (isEditableString != null) { isEditable = Boolean.valueOf(isEditableString).booleanValue(); } String description = null; IConfigurationElement[] descriptions = element .getChildren(IWorkbenchRegistryConstants.TAG_DESCRIPTION); if (descriptions.length > 0) { description = descriptions[0].getValue(); } return new FontDefinition(name, id, defaultMapping, value, categoryId, isEditable, description); } /** * Check for platform specific font values. This will return the * "best match" for the current platform. * * @param elements the elements to check * @return the platform specific font, if any */ private String getPlatformSpecificFontValue(IConfigurationElement[] elements) { return getFontValue(getBestPlatformMatch(elements)); } /** * Gets the font valu from the value attribute. * * @param element the element to check * @return the font string */ private String getFontValue(IConfigurationElement element) { if (element == null) { return null; } return element.getAttribute(IWorkbenchRegistryConstants.ATT_VALUE); } /** * Attempt to load the color value from the colorFactory attribute. * * @param element the element to load from * @return the value, or null if it could not be obtained */ private String checkColorFactory(IConfigurationElement element) { String value = null; if (element.getAttribute(IWorkbenchRegistryConstants.ATT_COLORFACTORY) != null || element.getChildren(IWorkbenchRegistryConstants.ATT_COLORFACTORY).length > 0) { try { IColorFactory factory = (IColorFactory) element .createExecutableExtension(IWorkbenchRegistryConstants.ATT_COLORFACTORY); value = StringConverter.asString(factory.createColor()); } catch (Exception e) { WorkbenchPlugin.log(RESOURCE_BUNDLE .getString("Colors.badFactory"), //$NON-NLS-1$ WorkbenchPlugin.getStatus(e)); } } return value; } /** * Read a theme. * * @param element the element to read * @return the new theme */ protected ThemeDescriptor readTheme(IConfigurationElement element) { ThemeDescriptor desc = null; String id = element.getAttribute(ThemeDescriptor.ATT_ID); if (id == null) { return null; } //see if the theme has already been created in another extension desc = (ThemeDescriptor) themeRegistry.findTheme(id); //if not, create it if (desc == null) { desc = new ThemeDescriptor(id); themeRegistry.add(desc); } //set the name as applicable desc.extractName(element); return desc; } /** * Read the theme extensions within a registry. * * @param in the registry to read * @param out the registry to write to */ public void readThemes(IExtensionRegistry in, ThemeRegistry out) { // this does not seem to really ever be throwing an the exception setRegistry(out); readRegistry(in, PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_THEMES); // support for old font definitions readRegistry(in, PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_FONT_DEFINITIONS); } /** * Set the output registry. * * @param out the output registry */ public void setRegistry(ThemeRegistry out) { themeRegistry = out; } }